﻿using NsbExtensions.Configuration;
using NsbExtensions.Endpoint.Management;
using NServiceBus.Unicast.Config;
using NServiceBus.Unicast.Subscriptions.Msmq.Config;
using NServiceBus.Unicast.Transport.Msmq.Config;
using ObjectBuilder;

namespace NsbExtensions.Endpoints.Msmq
{
    public class MsmqEndpointConfigurationManager
    {
        public static UnicastMsmqManagedEndpoint CreateManagedEndpointWith<T>(MsmqUnicastOptions options)
            where T : IBuilder
        {
            IBuilder builder = EndpointConfigurationManager.CreateBuilder<T>();
            ConfigureUnicastMsmqBus(builder, options);
            EndpointConfigurationManager.ConfigureManagedEndpoint
                <UnicastMsmqManagedEndpoint, EndpointManagementClientService>(builder);

            return (UnicastMsmqManagedEndpoint) builder.Build<IMessagingEndpoint>();
        }

        public static UnicastMsmqEndpoint CreateStandardEndpointWith<T>(MsmqUnicastOptions options) where T : IBuilder
        {
            //Create a IoC builder to construct our environment
            IBuilder builder = EndpointConfigurationManager.CreateBuilder<T>();

            //Setup the MSMQ Bus, Transport, Subscriptions, etc.
            ConfigureUnicastMsmqBus(builder, options);

            //Configure the Endpoint
            EndpointConfigurationManager.ConfigureEndpoint<UnicastMsmqEndpoint>(builder);

            //Build the endpoint and return
            return (UnicastMsmqEndpoint) builder.Build<IMessagingEndpoint>();
        }

        public static void ConfigureUnicastMsmqBus(IBuilder builder, MsmqUnicastOptions options)
        {
            if (options.SupportSubscriptions)
                ConfigureMsmqSubscriptionStorage(builder);

            ConfigureMsmqTransport(builder, options.TransactionalMessageHandling, options.PurgeOnStartup,
                                   options.UseXmlSerialization);
            ConfigureUnicastBus(builder, options.ImpersonateSender);
        }

        public static ConfigMsmqSubscriptionStorage ConfigureMsmqSubscriptionStorage(IBuilder builder)
        {
            return new ConfigMsmqSubscriptionStorage(builder);
        }

        public static ConfigMsmqTransport ConfigureMsmqTransport(IBuilder builder, bool isTransactional,
                                                                 bool purgeOnStartup, bool useXmlSerialization)
        {
            return new ConfigMsmqTransport(builder)
                .IsTransactional(isTransactional)
                .PurgeOnStartup(purgeOnStartup)
                .UseXmlSerialization(useXmlSerialization);
        }

        public static ConfigUnicastBus ConfigureUnicastBus(IBuilder builder, bool impersonateSender)
        {
            return new ConfigUnicastBus(builder)
                .ImpersonateSender(false);
        }
    }
}